<?php

namespace backend\modules\admin\controllers;

use Yii;
use yii\helpers\ArrayHelper;
use yii\web\Controller;
use yii\filters\VerbFilter;
use yii\web\NotFoundHttpException;
use backend\models\Clients;
use backend\modules\admin\models\Menu;
use backend\modules\admin\models\MenuTypes;
use backend\modules\admin\components\Helper;
use backend\modules\languages\models\Languages;
use backend\modules\admin\models\searchs\Menu as MenuSearch;

/**
 * MenuController implements the CRUD actions for Menu model.
 *
 * @author Misbahul D Munir <misbahuldmunir@gmail.com>
 * @since 1.0
 */
class MenuController extends Controller
{
    /**
     * @inheritdoc
     */
    public function behaviors()
    {
        return [
            'verbs' => [
                'class' => VerbFilter::class,
                'actions' => [
                    'delete' => ['post'],
                    'set-published' => ['post'],
                    'parent-item' => ['ajax']
                ],
            ],
        ];
    }

    /**
     * Lists all Menu models.
     * @return mixed
     * @throws \yii\base\InvalidConfigException
     */
    public function actionIndex()
    {
        $layout = Yii::$app->request->get('layout');
        $clientId = Yii::$app->request->get('client_id');
        $searchModel = new MenuSearch();

        if (Yii::$app->request->isPost) {
            $post = Yii::$app->request->post();
            if (!isset($post[$searchModel->formName()])) {
                $menuTypes = MenuTypes::find()
                    ->select('menutype')
                    ->where(['client_id' => $post['client']])
                    ->asArray()
                    ->all();
                $menuModel = Menu::findOne($post['id']);
                $menus = Menu::find()
                    ->where(['<>', 'home', 0])
                    ->andWhere([
                        'menutype' => ArrayHelper::getColumn($menuTypes, 'menutype'),
                        'language' => ['*', $menuModel->language]
                    ])
                    ->all();
                if (count($menus) > 0) {
                    foreach ($menus as $menu) {
                        $menu->home = 0;
                        $menu->save();
                    }
                }
                $menuModel->home = 1;
                $menuModel->save();
                Yii::$app->session->addFlash('success', Yii::t('rbac-admin', 'DEFAULT_HOME_SAVED'));
                return $this->refresh();
            }
        }


        if ($clientId) {
            $searchModel->client_id = $clientId;
        }
        $dataProvider = $searchModel->search(Yii::$app->request->bodyParams);

        return $this->render('index', [
            'layout' => $layout,
            'dataProvider' => $dataProvider,
            'searchModel' => $searchModel,
            'langList' => Languages::getList(),
            'clientList' => Clients::getList()
        ]);
    }

    /**
     * Displays a single Menu model.
     * @param int $id
     * @return string
     * @throws NotFoundHttpException
     */
    public function actionView($id)
    {
        return $this->render('view', [
            'model' => $this->findModel($id),
        ]);
    }

    /**
     * Creates a new Menu model.
     * If creation is successful, the browser will be redirected to the 'view' page.
     * @param $client_id
     * @return mixed
     */
    public function actionCreate($client_id)
    {
        $model = new Menu();

        $data = [];
        $xmlFields = null;

        if (Yii::$app->request->isPost) {
            $post = Yii::$app->request->post();
            if ($post['task'] == 'setType') {
                if (!empty($post['path'])) {
                    $client = Clients::findOne($client_id);
                    $xmlFile = Yii::getAlias('@' . $client->name) . base64_decode($post['path']);
                    if (is_file($xmlFile)) {
                        $xmlFields = $this->parseXmlFields($xmlFile);
                        $data['path'] = $xmlFile;
                        $data['client'] = $client->name;
                    }
                }
                $model->load($post);
                if (in_array($model->type, ['url', 'heading'])) {
                    $model->route = '';
                } elseif ($model->type === 'alias') {
                    $model->params = ['alias_redirect' => 0];
                }
                $data['type_alias'] = $post['type_alias'];
                $data['langCat'] = $post['langCat'];
                $data['route'] = $model->route;
            } elseif ($post['task'] == 'apply') {
                if ($model->load(Yii::$app->request->post()) && $model->save()) {
                    Helper::invalidate();
                    $model->setLftRgt();
                    return $this->redirect(['view', 'id' => $model->id]);
                }
            }
        }

        $menuTypes = MenuTypes::find()->where(['client_id' => $client_id])->all();

        $menuTypeList = ['' => Yii::t('rbac-admin', 'SELECT_MENU_TYPE')];
        foreach ($menuTypes as $menuType) {
            $menuTypeList[$menuType->menutype] = Yii::t('rbac-admin', $menuType->title);
        }
        $menuParentItems = $model->getParentMenus($model->menutype);
        $menuParentList = array_combine(array_column($menuParentItems, 'value'), array_column($menuParentItems, 'label'));

        return $this->render('create', [
            'model' => $model,
            'client_id' => $client_id,
            'menuTypeList' => $menuTypeList,
            'langList' => Languages::getList(),
            'data' => $data,
            'menuParentList' => $menuParentList,
            'xmlFields' => $xmlFields
        ]);
    }

    /**
     * Updates an existing Menu model.
     * If update is successful, the browser will be redirected to the 'view' page.
     * @param integer $id
     * @return mixed
     * @throws NotFoundHttpException
     */
    public function actionUpdate($id)
    {
        $model = $this->findModel($id);

        $data = [];
        $xmlFields = null;

        $menuType = MenuTypes::findOne(['menutype' => $model->menutype]);
        if (Yii::$app->request->isPost) {
            $post = Yii::$app->request->post();
            if ($post['task'] == 'setType') {
                if (!empty($post['path'])) {
                    $client = Clients::findOne($menuType->client_id);
                    $xmlFile = Yii::getAlias('@' . $client->name) . base64_decode($post['path']);
                    if (is_file($xmlFile)) {
                        $xmlFields = $this->parseXmlFields($xmlFile);
                        $data['path'] = $xmlFile;
                        $data['client'] = $client->name;
                    }
                }
                $model->load($post);
                if (in_array($model->type, ['url', 'heading'])) {
                    $model->route = '';
                } elseif ($model->type === 'alias') {
                    $model->params = ['alias_redirect' => 0];
                }
                $data['type_alias'] = $post['type_alias'];
                $data['langCat'] = $post['langCat'];
                $data['route'] = $model->route;
            } elseif ($post['task'] == 'apply') {
                if ($model->load($post) && $model->save()) {
                    Helper::invalidate();
                    $model->setLftRgt();
                    return $this->redirect(['view', 'id' => $model->id]);
                }
            }
        } else {
            $menuTypeModel = new MenuTypes();
            $menuTypeOption = $menuTypeModel->getOptions($menuType->client_id, $model->type, $model->route);
            $xmlFile = Yii::getAlias('@' . $menuTypeOption->client) . $menuTypeOption->path;
            if (is_file($xmlFile)) {
                $xmlFields = $this->parseXmlFields($xmlFile);
                $data['path'] = $xmlFile;
                $data['client'] = $menuTypeOption->client;
            }
            $data['langCat'] = $menuTypeOption->langCat;
            $data['type_alias'] = Yii::t($menuTypeOption->langCat, $menuTypeOption->title);
            $data['route'] = $model->route;
        }

        $menuTypes = MenuTypes::find()->where(['client_id' => $menuType->client_id])->all();

        $menuTypeList = ['' => Yii::t('rbac-admin', 'SELECT_MENU_TYPE')];
        foreach ($menuTypes as $mType) {
            $menuTypeList[$mType->menutype] = Yii::t('rbac-admin', $mType->title);
        }

        $menuParentItems = $model->getParentMenus($model->menutype);
        $menuParentList = array_combine(array_column($menuParentItems, 'value'), array_column($menuParentItems, 'label'));

        return $this->render('update', [
            'model' => $model,
            'data' => $data,
            'menuParentList' => $menuParentList,
            'langList' => Languages::getList(),
            'menuTypeList' => $menuTypeList,
            'client_id' => $menuType->client_id,
            'xmlFields' => $xmlFields,
        ]);
    }

//    public function actionUpdate2($id)
//    {
//        $model = $this->findModel($id);
//
//        $typeAlias = '';
//        $xmlFields = null;
//        $data = [];
//
//        if (Yii::$app->request->isPost) {
//            $post = Yii::$app->request->post();
//            if ($post['task'] == 'setType') {
//                $model->load($post);
//                if (in_array($model->type, ['url', 'heading'])) {
//                    $model->route = '';
//                } elseif ($model->type === 'alias') {
//                    $model->params = ['alias_redirect' => 0];
//                }
//                $typeAlias = $post['type_alias'];
//            } elseif ($post['task'] == 'apply') {
//                if ($model->load(Yii::$app->request->post()) && $model->save()) {
//                    Helper::invalidate();
//                    $model->setLftRgt();
//                    return $this->redirect(['view', 'id' => $model->id]);
//                }
//            }
//        } else {
//            switch ($model->type) {
//                case 'url':
//                    $typeAlias = Yii::t('rbac-admin', 'MENUS_TYPE_EXTERNAL_URL');
//                    break;
//                case 'alias':
//                    $typeAlias = Yii::t('rbac-admin', 'MENUS_TYPE_ALIAS');
//                    break;
//                case 'separator':
//                    $typeAlias = Yii::t('rbac-admin', 'MENUS_TYPE_SEPARATOR');
//                    break;
//                case 'heading':
//                    $typeAlias = Yii::t('rbac-admin', 'MENUS_TYPE_HEADING');
//                    break;
//                default :
//                    $typeAlias = $model->getNameLang($model->id);
//            }
//        }
//
//        $menuType = MenuTypes::findOne(['menutype' => $model->menutype]);
//        $menuTypes = MenuTypes::find()->where(['client_id' => $menuType->client_id])->all();
//        $menuTypeList = ['' => Yii::t('rbac-admin', 'SELECT_MENU_TYPE')];
//        foreach ($menuTypes as $menuType) {
//            $menuTypeList[$menuType->menutype] = Yii::t('rbac-admin', $menuType->title);
//        }
//
//        $menuParentItems = $model->getParentMenus($model->menutype, $model->id);
//        $menuParentList = array_combine(array_column($menuParentItems, 'value'), array_column($menuParentItems, 'label'));
//
//        if (is_string($model->data)) {
//            $model->data = json_decode($model->data, true);
//        }
//
//        return $this->render('update', [
//            'model' => $model,
//            'client_id' => $menuType->client_id,
//            'menuTypeList' => $menuTypeList,
//            'langList' => Languages::getList(),
//            'typeAlias' => $typeAlias,
//            'menuParentList' => $menuParentList,
//            'xmlFields' => $xmlFields,
//            'data' => $data
//        ]);
//    }

    /**
     * 设置发布状态
     * @return \yii\web\Response
     * @throws NotFoundHttpException
     */
    public function actionSetPublished()
    {
        $id = Yii::$app->request->post('id');

        $model = $this->findModel($id);
        if ($model->published === 1) {
            $model->published = 0;
        } else {
            $model->published = 1;
        }

        if ($model->save()) {
            $type = 'success';
            $msg = $model->published === 1 ? 'MENU_PUBLISH_SUCCESS' : 'MENU_UNPUBLISH_SUCCESS';
        } else {
            $type = 'error';
            $msg = $model->published === 1 ? 'MENU_UNPUBLISH_FAILED' : 'MENU_PUBLISH_FAILED';
        }

        Yii::$app->session->setFlash($type, Yii::t('rbac-admin', $msg));

        $returnUrl = json_decode(Yii::$app->request->post('returnUrl'), true);
        unset($returnUrl['get']['_pjax']);
        $url = $returnUrl['get'];
        array_unshift($url, $returnUrl['route']);

        return $this->redirect($url);
    }

    /**
     * Deletes an existing Menu model.
     * If deletion is successful, the browser will be redirected to the 'index' page.
     * @param integer $id
     * @return mixed
     * @throws NotFoundHttpException
     * @throws \Throwable
     * @throws yii\db\StaleObjectException
     */
    public function actionDelete($id)
    {
        $this->findModel($id)->delete();
        Helper::invalidate();
        $model = new Menu();
        $model->setLftRgt();
        return $this->redirect(['index']);
    }

    public function actionParentItems($menuType = '')
    {
        $menu = new Menu();
        return json_encode($menu->getParentMenus($menuType));
    }

    /**
     * Finds the Menu model based on its primary key value.
     * If the model is not found, a 404 HTTP exception will be thrown.
     * @param integer $id
     * @return Menu the loaded model
     * @throws NotFoundHttpException if the model cannot be found
     */
    protected function findModel($id)
    {
        if (($model = Menu::findOne($id)) !== null) {
            return $model;
        } else {
            throw new NotFoundHttpException(Yii::t('common', 'REQUESTED_PAGE_NOT_EXIST'));
        }
    }

    /**
     * 解析XML文件
     * @param $xmlFile
     * @return object
     */
    protected function parseXmlFields($xmlFile)
    {
        $xml = simplexml_load_file($xmlFile);
        $fieldObj = new \stdClass();
        foreach ($xml->fields as $fields) {
            $fieldsName = (string)$fields->attributes()->name;
//            $fieldObj->$fieldsName = new \stdClass();
            $fieldObj->$fieldsName = $fields;
//            foreach ($fields->fieldset as $fieldset) {
//                $fieldsetName = (string)$fieldset->attributes()->name;
//                $fieldObj->$fieldsName->$fieldsetName = new \stdClass();
//                $fieldObj->$fieldsName->$fieldsetName->_attributes = $fieldset->attributes();
//                foreach ($fieldset->field as $field) {
//                    $fieldName = (string)$field->attributes()->name;
//                    $fieldName = str_replace(['[', ']'], ['_', ''], $fieldName);
//                    $fieldObj->$fieldsName->$fieldsetName->$fieldName = new \stdClass();
//                    foreach ($field->attributes() as $item) {
//                        $itemAttrName = $item->getName();
//                        $fieldObj->$fieldsName->$fieldsetName->$fieldName->$itemAttrName = (string)$item;
//                    }
//                }
//            }
        }

        return $fieldObj;
    }
}
